package com.yenlien.traceyun.business.controller;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.business.bean.RestURL;
import com.yenlien.traceyun.business.feign.ProvideClientS;
import com.yenlien.traceyun.business.interceptor.CommonProperties;
import com.yenlien.traceyun.business.interceptor.UserAuthUtil;
import com.yenlien.traceyun.business.service.rest.RestService;
import com.yenlien.traceyun.business.service.rest.usercenter.UserRestService;
import com.yenlien.traceyun.common.constant.Constants;
import com.yenlien.traceyun.common.crypt.TokenUtil;
import com.yenlien.traceyun.common.exception.TokenException;
import com.yenlien.traceyun.common.utils.RedisUtils;
import com.yenlien.traceyun.webase.controller.BaseController;
import com.yenlien.traceyun.webase.utils.CheckParams;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.websocket.server.PathParam;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: bigwangy@sina.com
 * @create: 2020-03-06
 * @description:
 **/
@Slf4j
@Api(tags = "用户管理模块")
@RestController
@RequestMapping(value = "/user")
public class UserController extends BaseController {

    @Autowired
    private UserRestService userRestService;

    @Autowired
    private CommonProperties tokenProperties;

    @Autowired
    private RestService restService;

    @Autowired
    private ProvideClientS userService;

    @Autowired
    private RedisUtils redisUtils;

    @Value("${traceyun.app.id}")
    private String appId;

    @Value("${dddl.app.id}")
    private String clientId;

    @Value("${dddl.app.secret}")
    private String appSecret;

    /**
     * 登录
     *
     * @param userInfo
     * @return
     */
    @ApiOperation(value = "登录接口", notes = "参数示例：{\"username\":\"admin\",\"password\":\"123123\"}")
    @PostMapping(value = "/login")
    public Object login(@RequestBody JSONObject userInfo) {
        CheckParams.checkJson(userInfo, new String[]{"username", "password"});
        JSONObject userJson = userRestService.login(userInfo.getString("username"), userInfo.getString("password"), appId);
        JSONObject user = userJson.getJSONObject("userInfo");
        JSONObject result = new JSONObject();
//        int expire = tokenProperties.getExpire();
        int expire = 60 * 24 * 10;
        if (userInfo.containsKey("expire")) {
            expire = userInfo.getIntValue("expire");
        }
        result.put("token", TokenUtil.getToken(user.toJSONString(), tokenProperties.getSecret(), expire));
        result.put("userInfo", user);
        result.put("appMenus", userJson.getJSONArray("appMenus"));
//        result.put("appVersion", userJson.getJSONObject("customAppVersion"));
        return result;
    }

    /**
     * 登录(pc)
     *
     * @param userInfo
     * @return
     */
    @PostMapping(value = "/logins")
    public Object logins(@RequestBody JSONObject userInfo, HttpServletRequest request) {
        String session = (String) request.getSession().getAttribute("session");
        CheckParams.checkJson(userInfo, new String[]{"username", "password"});
        String checkCode = userInfo.getString("checkCode");
//        if (!(session != null && checkCode != null && checkCode.toLowerCase().equals(session))) {
//            throw new BusinessException("验证码错误");
//        }
        JSONObject userJson = userRestService.login(userInfo.getString("username"), userInfo.getString("password"), appId);
        JSONObject user = userJson.getJSONObject("userInfo");
        JSONObject result = new JSONObject();
        int expire = 60 * 24;
        if (userInfo.containsKey("expire")) {
            expire = userInfo.getIntValue("expire");
        }
        result.put("token", TokenUtil.getToken(user.toJSONString(), "123456", expire));
        result.put("userInfo", user);
        JSONArray appMenus = userJson.getJSONArray("appMenus");
        JSONObject jsonObject = null;
        try {
            jsonObject = appMenus.getJSONObject(0);
        } catch (Exception e) {
        }
        if (jsonObject != null) {
//            if ("fruit".equals(userInfo.getString("type")) && "种植平台".equals(jsonObject.getString("appName"))) {
            if ("种植平台".equals(jsonObject.getString("appName"))) {
                appMenus.remove(jsonObject);
                JSONArray flowMenus = jsonObject.getJSONArray("flowMenus");
                JSONArray configMenus = jsonObject.getJSONArray("configMenus");
                //果园SASS登录则舍弃 的菜单栏
//                List<String> menuList = Arrays.asList("首页", "数字地图", "基地管理", "投入品管理", "种植管理", "采收管理", "企业设置", "员工管理", "权限配置", "供应商管理", "客户管理", "基源管理", "常用单位", "设备管理");
                List<String> menuList = Arrays.asList("加工管理", "检验检测", "分包管理", "赋码管理", "订单管理", "仓储管理", "追溯查询");
                jsonObject.put("flowMenus", flowMenus.stream().filter(x ->
                        !menuList.contains(JSONObject.parseObject(JSONObject.toJSONString(x)).getString("name"))
                ).collect(Collectors.toList()));
                jsonObject.put("configMenus", configMenus.stream().filter(x ->
                        !menuList.contains(JSONObject.parseObject(JSONObject.toJSONString(x)).getString("name"))
                ).collect(Collectors.toList()));
                appMenus.add(jsonObject);
            }
        }
        result.put("appMenus", appMenus);
        result.put("appVersion", userJson.getJSONObject("customAppVersion"));
        return result;
    }


    /**
     * 根据code获取用户权限信息
     * @param
     * @return
     */
    @GetMapping("/findUserByAccessToken")
    public Object findUserByAccessToken(String code) {
        String accessToken = (String) redisUtils.get(code);
        if (StringUtils.isEmpty(accessToken)) {
            return fail("accessToken为空!");
        }
        log.info("接收到的access_token为:====={}", accessToken);
        String url = String.format("http://182.132.59.143:8083/api/oauth/userinfo?access_token=%s", accessToken);
        //获取用户信息
        String userJson = HttpRequest.get(url)
                .execute()
                .body();
        log.info("请求的用户信息为:======{}", userJson);
        JSONObject jsonObject = JSONObject.parseObject(userJson);
        String userId = jsonObject.getJSONObject("data").getString("id");
        JSONObject userData = userService.loginV1(userId);
        JSONObject user = userData.getJSONObject("userInfo");
        System.out.println(user);
        JSONObject result = new JSONObject();
        result.put("token", TokenUtil.getToken(user.toJSONString(), "123456", 60 * 24));
        result.put("userInfo", user);
        result.put("appMenus", userData.getJSONArray("appMenus"));
        result.put("appVersion", user.getJSONObject("customAppVersion"));
        return result;
    }


    /**
     * 根据code获取accessToken(退出登录使用)
     * @param code
     * @return
     */
    @GetMapping("/findAccessTokenByCode")
    public Object findAccessTokenByCode(String code) {
        String accessToken = (String) redisUtils.get(code);
        if (StringUtils.isEmpty(accessToken)) {
            return fail("accessToken为空!");
        }
        //删除code
        redisUtils.del(code);
        return accessToken;
    }

    /**
     * 登录成功后回调该地址得到code,根据code获取到access_token
     *
     * @param code
     * @param response
     * @return
     */
    @GetMapping("/gainAccessToken")
    public Object gainAccessToken(String code, HttpServletResponse response) {
        log.info("code=================={}", code);
        if (!StringUtils.isEmpty(code)) {
            //根据code获取access_token
            String result = HttpRequest.post("http://182.132.59.143:8083/api/oauth/token")
                    .header("Content-Type", "application/x-www-form-urlencoded")
                    .form("code", code)
                    .form("client_id", clientId)
                    .form("client_secret", appSecret)
                    .form("grant_type", "authorization_code")
                    .form("redirect_uri", Constants.REDIRECT_URI)
                    .execute()
                    .body();
            JSONObject jsonObject = JSONObject.parseObject(result);
            String accessToken = jsonObject.getString("access_token");
            String redirect = "http://app.cpzsyun.com/dege?code=" + code;
            redisUtils.set(code, accessToken, 3600);
            try {
                response.sendRedirect(redirect);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return null;
        }
        return fail("code为空!");
    }

    @GetMapping("/getCookie")
    public Object getCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        String targetCookieName = "access_token";
        // 遍历 Cookie 数组，查找目标名称的 Cookie
        Cookie targetCookie = null;
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(targetCookieName)) {
                    targetCookie = cookie;
                    break;
                }
            }
        }
        // 判断目标 Cookie 是否找到
        if (targetCookie != null) {
            // 找到了目标 Cookie，获取其值
            String targetCookieValue = targetCookie.getValue();
            // 进行后续的处理逻辑
            log.info("accessToken================={}", targetCookieValue);
            return success(targetCookieValue);
        } else {
            // 没有找到目标 Cookie
            log.info("accessToken=================null");
            return fail("accessToken没找到");
        }
    }


//    @Autowired
//    private TimeDao timeDao;
//    @Value("${a.time}")
//    private Long day;
//  junlian
//    @GetMapping("/checkCode")
//    public Object checkCode(HttpServletRequest request) {
//        List<Time> all = timeDao.findAll();
//        if(CollectionUtils.isEmpty(all))
//            return fail("您的使用授权时间已到请联系，请联系厂商");
//        if(all.size() > 1)
//            return fail("您的使用授权时间已到请联系，请联系厂商");
//        if(Duration.between(LocalDateTime.parse(all.get(0).getTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), LocalDateTime.now()).toDays() > day){
//            return fail("您的使用授权时间已到请联系，请联系厂商");
//        }
//        String checkCode = getCheckCode();
//        HttpSession session = request.getSession(true);
//        session.setAttribute("session", checkCode.toLowerCase());
//        return success(checkCode);
//    }

    @GetMapping("/checkCode")
    public Object checkCode(HttpServletRequest request) {
        String checkCode = getCheckCode();
        HttpSession session = request.getSession(true);
        session.setAttribute("session", checkCode.toLowerCase());
        return success(checkCode);
    }

    /**
     * 刷新token
     *
     * @param request
     * @return
     */
    @GetMapping(value = "/refresh/token")
    public Object refresh(HttpServletRequest request) throws TokenException {
        String refresh = request.getHeader("refresh");
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(refresh)) {
            throw new TokenException("refresh is not exist");
        }
        if (StringUtils.isEmpty(token)) {
            throw new TokenException("未登录");
        }
        TokenUtil.veryRefresh(refresh, tokenProperties.getSecret());
        JSONObject result = new JSONObject();
        result.put("token", TokenUtil.getToken(TokenUtil.getBody(token), tokenProperties.getSecret(), tokenProperties.getExpire()));
        result.put("refresh", TokenUtil.getRefreshToken(tokenProperties.getSecret(), tokenProperties.getRefresh()));
        return result;
    }

    /**
     * 用户注册
     *
     * @param map
     * @return
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public Object register(@RequestParam Map<String, Object> map, HttpServletRequest request) throws Exception {
        List<MultipartFile> files = new ArrayList<>();
        if (!StringUtils.isEmpty(((MultipartHttpServletRequest) request).getFile("files"))) {
            files = ((MultipartHttpServletRequest) request).getFiles("files");
        }
        map.put("companyId", UserAuthUtil.getLoginUser().getCompanyId());
        return userRestService.save(map, files);
    }

    @RequestMapping(value = "/save2", method = RequestMethod.POST)
    public Object register2(@RequestBody JSONObject jsonObject) throws Exception {
        jsonObject.put("companyId", UserAuthUtil.getLoginUser().getCompanyId());
        return userRestService.save2(jsonObject);
    }


    /**
     * 用户修改
     *
     * @param map
     * @return
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public Object update(@RequestParam Map<String, Object> map, HttpServletRequest request) throws Exception {
        List<MultipartFile> files = new ArrayList<>();
        if (!StringUtils.isEmpty(((MultipartHttpServletRequest) request).getFile("files"))) {
            files = ((MultipartHttpServletRequest) request).getFiles("files");
        }
        return userRestService.update(map, files);
    }

    @RequestMapping(value = "/update2", method = RequestMethod.POST)
    public Object update2(@RequestBody JSONObject jsonObject) throws Exception {
        return userRestService.update2(jsonObject);
    }

    @ApiOperation(value = "根据用户id获取用户信息")
    @RequestMapping(value = "/findById/{id}", method = RequestMethod.GET)
    public Object findById(@PathVariable String id) {
        return userRestService.findById(id);
    }

    @RequestMapping(value = "/findByList", method = RequestMethod.POST)
    public Object findByList(@RequestBody JSONObject user) {
        user.put("companyId", UserAuthUtil.getLoginUser().getCompanyId());
        return userRestService.findByList(user);
    }

    @ApiOperation(value = "获取用户下拉列表")
    @RequestMapping(value = "/findByAll", method = RequestMethod.GET)
    public Object findByAll(@PathParam(value = "name") String name) {
        JSONObject param = new JSONObject();
        param.put("name", name);
        param.put("companyId", UserAuthUtil.getLoginUser().getCompanyId());
        return userRestService.findByAll(param);
    }

    @PostMapping(value = "/locked")
    public Object locked(@RequestBody JSONObject params) {
        return userRestService.locked(params);
    }

    @RequestMapping(value = "/checkPassword", method = RequestMethod.POST)
    public Object checkPassword(@RequestBody JSONObject param) {
        CheckParams.checkJson(param, new String[]{"userId", "password"});
        return userRestService.checkPassword(param);
    }

    @PostMapping(value = "/save/appmenus")
    public Object setUserAppmenus(@RequestBody JSONObject params) {
        CheckParams.checkJson(params, new String[]{"userId"});
        return userRestService.setUserAppmenus(params);
    }

    /**
     * 产生4位随机字符串
     */
    private String getCheckCode() {
        String base = "0123456789ABCDEFGabcdefg";
        int size = base.length();
        Random r = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 4; i++) {
            //产生0到size-1的随机值
            int index = r.nextInt(size);
            //在base字符串中获取下标为index的字符
            char c = base.charAt(index);
            //将c放入到StringBuffer中去
            sb.append(c);
        }
        return sb.toString();
    }

    /**
     * 员工数量统计
     */
    @PostMapping(value = "/userNum")
    public Object userNum(@RequestBody JSONObject params) {
        if (params != null) {
            return success(restService.postJson(RestURL.USERCENTER + "user/userNum", params));
        }
        return fail("companyId不能为空");
    }
}
